LeetCode刷题 | 算法
数据结构与算法
- LeetCode两题(两数之和,两数相加)
- 为了复习数据结构和算法刷的题
- 用比较白话的方式表达个人的理解
一、两数之和
给定一个数组,以及一个数,求数组内是否存在两数和能得到这个数的,有就输出位置
时间复杂度减少需要使用到哈希表
1.暴力穷举法
- for循环将所有可能循环遍
- 时间复杂度:O(n2)
- 空间复杂度:O(1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public int[] twoSum(int[] nums, int target) {
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
if (nums[j] == target - nums[i]) {
return new int[] { i, j };
}
}
}
throw new IllegalArgumentException("No two sum solution");
}
/*
for循环所有可能,每个数都和其他数进行匹配
效率底,比较傻瓜式
*/
2.两遍哈希表
- 时间复杂度:O(n)
- 空间复杂度:O(n)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
map.put(nums[i], i);
}
for (int i = 0; i < nums.length; i++) {
int complement = target - nums[i];
if (map.containsKey(complement) && map.get(complement) != i) {
return new int[] { i, map.get(complement) };
}
}
throw new IllegalArgumentException("No two sum solution");
}
/*
1.使用哈希表(对于iOS开发,哈希表就相当于字典),将数组中的值以键值对的方式放到哈希表中
2.条件已知 "和" -> target,以及其中一个数(就是数组取的每个值), 那我们就能得到另外一个数是多少
即 target - nums[i] = ?
求得的 ? 可以作为key 数组里面的值变成了Key,每个值对应的下标变成了Value
问题简单化,使用哈希表键值对的特性,巧妙利用 '数组值' 作为哈希表的 'key''对应下标'作为哈希表的'value'
判断是否存在,存在的话就说明有对应两数,不存在就没有
*/
3.一遍哈希表
1 | public int[] twoSum(int[] nums, int target) { |
二、两数相加
1.单链表
- 这里必须要复习下单链表的逆序(虽然用处不大)
- 单链表逆序
- 本意是使用prev所指向的nil 从头结点开始进行逆序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
161.
head->next = prev; //将head的next指针指向prev对应的节点
prev = head; //将prev指向head所在的节点,这样head以及prev同时指向头结点
head = next; //将head向后移,这个时候head和next指向的都是next所在的节点
next = head->next; //最后next 指向head所指向的next(因为前一步head已经和next指向了同一个节点)将next向后移
2.
next = head->next;
head->next = prev;
prev = head;
head = next;
这里的两种循环本体的区别
第一种在循环到最后当head和next都指向nil的时候,next还需要向后移一步,这个时候肯定是越界的
第二种方法将 next = head->next; 提到了第一步,先后移,巧妙的避开了第一种的弊端
2.言归正传
给两个单链表,用于保存两个非负整数,逆序存放,求两数之和
(2 -> 6 -> 4) + (1 -> 7 -> 3) = ( 3 -> 3 -> 8)
462 + 371 = 833
这里的逆序已经是提供了便利的条件了
将两个链表顺序执行相加,若大于10,后一位加1
若链表执行到nil 表示执行到了链表尾部节点
当两个链表指针指向的节点都为空时候 结束
题目可以出的更麻烦一点,数字不逆序,这样在计算的时候需要对两个单链表进行一遍的逆序再执行如下操作
1 | public ListNode addTwoNumbers(ListNode l1, ListNode l2) { |